package com.xiaochong.bitong.api.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xc.logclient.utils.LogTrace;
import com.xiaochong.bitong.api.config.hbase.HbaseBaseQueryComponent;
import com.xiaochong.bitong.api.constant.ReturnCode;
import com.xiaochong.bitong.api.utils.StringUtil;
import com.xiaochong.service.common.config.redis.RedisServer;
import com.xiaochong.tir.common.data.hbasepo.*;
import com.xiaochong.tir.common.data.vo.*;
import com.xiaochong.tir.common.data.vo.app.MarketAnalysisVo;
import com.xiaochong.tir.common.data.vo.app.MarketIndexVo;
import com.xiaochong.tir.common.util.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @Project : xc-tir
 * @Package Name : com.xiaochong.bitong.api.service
 * @Description : TODO 大盘指数相关服务
 * @Author : daizhiqing@xiaochong.com
 * @Creation Date : 2018年08月14日下午5:29
 * @ModificationHistory Who When What
 */
@Service
public class MarketIndexService {

    @Autowired
    RedisServer redisServer;

    @Autowired
    HbaseBaseQueryComponent hbaseBaseQueryComponent;

    /**
     * 大盘指数
     * @param type
     * @return
     */
    public ApiResultVo<ApiMarketIndexVo> getGrailIndex(int type){
        Long start = System.currentTimeMillis();
        ApiResultVo<ApiMarketIndexVo> resultVo = new ApiResultVo<>();
        ApiMarketIndexVo voList = new ApiMarketIndexVo();
        resultVo.setDataStamp(System.currentTimeMillis());

        ChartVo chartVo = new ChartVo();

        try {

            switch (type){
                case 1:
                    //3小时
                    chartVo = redisServer.get(RedisKeyApp.APP_TIR_BROADER_INDEX_CHART_3H , ChartVo.class);
                    break;
                case 2:
                    //24小时
                    chartVo = redisServer.get(RedisKeyApp.APP_TIR_BROADER_INDEX_CHART_24H , ChartVo.class);
                    break;
                case 3:
                    //7天
                    chartVo = redisServer.get(RedisKeyApp.APP_TIR_BROADER_INDEX_CHART_7D , ChartVo.class);
                    break;
                case 4:
                    //30天
                    chartVo = redisServer.get(RedisKeyApp.APP_TIR_BROADER_INDEX_CHART_30D , ChartVo.class);
                    break;
                case 5:
                    //全部（一年）
                    chartVo = redisServer.get(RedisKeyApp.APP_TIR_BROADER_INDEX_CHART_1Y , ChartVo.class);
                    break;
            }
            voList.setChart(chartVo);
            //查询当前最新数据
            String grailIndex = redisServer.get(RedisKeysUtils.TIR_BROADER_INDEX);
            LogTrace.info("大盘指数-从reids获取的数据","返回数据",grailIndex);
            if(StringUtils.isNotBlank(grailIndex)){
                BroaderIndex bi = JSON.parseObject(grailIndex,BroaderIndex.class);
                voList.setChange(bi.getBroaderRiseFall().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString());
                voList.setIndex(bi.getBroaderIndex().setScale(2,BigDecimal.ROUND_DOWN).toString());
                voList.setDifference( StringUtil.getDoubleTwo( Double.parseDouble( voList.getChange() )*Double.parseDouble( voList.getIndex() )/100 )+"" );
            }else {
                resultVo.setCode(ReturnCode.DATA_NOT_EXIST);
                return  resultVo;
            }
            voList.setTir("APP大盘指数");
            /**
             * App端大盘附属数据
             */
            MarketIndexVo marketIndexVo = redisServer.get(RedisKeyApp.MARKET_DATA , MarketIndexVo.class);
            voList.setMarketIndexVo(marketIndexVo);
            resultVo.setData(voList);
            resultVo.setCode(ReturnCode.SUCCESS);
            resultVo.setTradeId( LogTrace.getTrace().getTraceId() );
            Long end = System.currentTimeMillis();
            LogTrace.info("大盘指数","耗时",String.valueOf(end-start));
            return resultVo;
        }catch (Exception e){
            resultVo.setCode(ReturnCode.ERROR);
            e.printStackTrace();
            resultVo.setTradeId( LogTrace.getTrace().getTraceId() );
            LogTrace.error("大盘指数"+type,e);
            return resultVo;
        }

    }


    /**
     * 大盘强弱分析
     * @return
     */
    public ApiResultVo<MarketAnalysisVo> getMarketAnalysisTotalResult() {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        MarketAnalysisVo vo = new MarketAnalysisVo();
        resultVo.setData(vo);
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        try {
            //去redis中取量能变化、赚钱效应、权重表现  WeightsPerformance
            String grailIndex = redisServer.get(RedisKeysUtils.INDEX_EVERY_DAY_RECORDING);
            LogTrace.info("大盘分析-量能变化、赚钱效应、权重表现redis数据","数据",grailIndex);
            //去redis涨跌统计
            String highOrLow = redisServer.get(RedisKeysUtils.TIR_CHANGE_STATISTICS);
            LogTrace.info("大盘分析-涨跌统计redis数据","数据",highOrLow);
            if(org.apache.commons.lang3.StringUtils.isBlank(grailIndex) && org.apache.commons.lang3.StringUtils.isBlank(highOrLow)){
                resultVo.setCode(ApiResultCodeUtils.SYSTEM_NULL.getCode());
                resultVo.setMessage(ApiResultCodeUtils.SYSTEM_NULL.getMsg());
                return resultVo;
            }
            Map<String,Object> marketMap = JSON.parseObject(grailIndex);
            BigDecimal scoreMoneyEffect;
            BigDecimal scoreWeightsPerformance;
            BigDecimal scoreStatistics ;
            BigDecimal scoreQuantumEnergy ;
            BigDecimal total = new BigDecimal(0);
            if(marketMap != null){
                for (Map.Entry m :marketMap.entrySet()){
                    if("moneyEffect".equals(m.getKey())){ //MoneyEffect
                        MoneyEffect bi = JSON.parseObject(JSON.toJSONString(m.getValue()),MoneyEffect.class);
                        if(bi != null && bi.getScore() != null){
                            LogTrace.info("大盘强度分析","赚钱效应分数",String.valueOf(bi.getScore()));
                            scoreMoneyEffect = new BigDecimal(bi.getScore()).multiply(BigDecimal.valueOf(0.15));
                            total = total.add(scoreMoneyEffect);
//                            vo.setMakeMoneyEffect(bi.getComment()!=null?bi.getComment():"");
                        }
                    }else if("weightsPerformance".equals(m.getKey())){
                        WeightsPerformance bi = JSON.parseObject(JSON.toJSONString(m.getValue()),WeightsPerformance.class);
                        if(bi != null && bi.getScore() != null){
                            scoreWeightsPerformance = new BigDecimal(bi.getScore()).multiply(BigDecimal.valueOf(0.3));
                            total = total.add(scoreWeightsPerformance);
                            LogTrace.info("大盘强度分析","权重表现分数",String.valueOf(bi.getScore()));
//                            vo.setWeightPerformance(bi.getComment()!=null?bi.getComment():"");
                        }
                    }else if("quantumEnergy".equals(m.getKey())){
                        QuantumEnergy bi = JSON.parseObject(JSON.toJSONString(m.getValue()),QuantumEnergy.class);
                        if(bi != null && bi.getScore() != null){
                            scoreQuantumEnergy = new BigDecimal(bi.getScore()).multiply(BigDecimal.valueOf(0.25));
                            total = total.add(scoreQuantumEnergy);
                            LogTrace.info("大盘强度分析","量能变化分数",String.valueOf(bi.getScore()));
//                            vo.setEnergyChange(bi.getComment()!=null?bi.getComment():"");
                        }
                    }
                }
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(highOrLow)){
                CurrentcyHighOrLow hl = JSON.parseObject(highOrLow,CurrentcyHighOrLow.class);
                scoreStatistics = new BigDecimal(Double.valueOf(hl.getScore())).multiply(BigDecimal.valueOf(0.3));
                total = total.add(scoreStatistics);
                LogTrace.info("大盘强度分析","涨跌统计分数分数",String.valueOf(hl.getScore()));
//                vo.setStatistics(hl.getEvaluate());
            }
            //计算4个比例分数，以及给出评语
            LogTrace.info("大盘强度","total分数",total.toString());
            vo.setMarketScore(String.valueOf(total.setScale(1,BigDecimal.ROUND_DOWN)));
            double num = Double.valueOf(String.valueOf(total));
            if(num < 4){
                vo.setResult("大盘处于走弱态势");
            }else if(num >= 4 && num < 6){
                vo.setResult("大盘处于盘整态势");
            }else{
                vo.setResult("大盘处于走强态势");
            }
            //获取近7日趋势
            vo.setLast7status(redisServer.get(RedisKeysUtils.BROADER_DATA_7_STATUS));
            //获取近30日趋势
//            vo.setLast30status(rediscConfig.get(RedisKeysUtils.BROADER_DATA_30_STATUS));

            resultVo.setCode(ReturnCode.SUCCESS);
            Long end = System.currentTimeMillis();
            LogTrace.info("APP大盘强弱分析","耗时",String.valueOf(end-start));
            return resultVo;
        }catch (Exception e){
            LogTrace.error("APP大盘强弱分析",e);
            e.printStackTrace();
            resultVo.setCode(ReturnCode.ERROR);
            resultVo.setMessage(e.getMessage());
            return resultVo;
        }

    }

    /**
     * 涨跌统计
     * @return List<T>
     */
    public ApiResultVo getRiseAndFall() {
        ApiResultVo resultVo=new ApiResultVo();

        //涨跌统计实体
        CurrentcyHighOrLow curentcyHigh=null;

        try {
            Long jStart = System.currentTimeMillis();
            String fallStr=redisServer.get(RedisKeysUtils.TIR_CHANGE_STATISTICS);
            LogTrace.info("涨跌统计redis查询","耗时",String.valueOf(System.currentTimeMillis()-jStart));
            LogTrace.info("涨跌统计", "riseAndFall涨跌统计接口redis返回:",fallStr);
            if (fallStr!=null){
                curentcyHigh = JSON.parseObject(fallStr, CurrentcyHighOrLow.class);
            }

            int total  =  curentcyHigh.getUpCount()+curentcyHigh.getDownCount();

            GraliIntensity graliIntensity=new GraliIntensity();
            graliIntensity.setInterpretationId(1);
            graliIntensity.setInterpretation("涨跌统计");
//            Date date = new Date(Long.parseLong(curentcyHigh.getDateTime()));
//            graliIntensity.setTime( DateUtils.dateFormatString(date ,DateTimeFormatter.ofPattern("HH:mm")));
           String[] strs =  curentcyHigh.getDateTime().split(" ");
            graliIntensity.setTime(strs[1].substring(0 ,5));
            graliIntensity.setScore(curentcyHigh.getScore());
            graliIntensity.setResult(curentcyHigh.getEvaluate());
            graliIntensity.setCurrencys(total);
            graliIntensity.setAllCount(total+"");
            graliIntensity.setUpCount( curentcyHigh.getUpCount()+"" );
            graliIntensity.setDownCount( curentcyHigh.getDownCount()+"" );

            ChartVo vo=new ChartVo();
            List<String> xList=new ArrayList<String>();
            xList.add("-10%以下");
            xList.add("-10%至-6%");
//            xList.add("-6%至-4%");
//            xList.add("-4%至-2%");
            xList.add("-6%至-2%");
            xList.add("-2%至0%");
            xList.add("0%至2%");
//            xList.add("2%至4%");
//            xList.add("4%至6%");
            xList.add("2%至6%");
            xList.add("6%至10%");
            xList.add("10%以上");
            vo.setX(xList);
            List<Integer> yList=new ArrayList<Integer>();
            yList.add(curentcyHigh.getF10());
            yList.add(curentcyHigh.getF10Tof6());
//            yList.add(curentcyHigh.getF6Tof2());
//            yList.add(curentcyHigh.getF2To0());
            yList.add(curentcyHigh.getF6Tof2()+curentcyHigh.getF2To0());
            yList.add(curentcyHigh.getZ0Toz2());
            yList.add(curentcyHigh.getZ2Toz4());
//            yList.add(curentcyHigh.getZ4Toz6());
//            yList.add(curentcyHigh.getZ6Toz8());
            yList.add(curentcyHigh.getZ4Toz6()+curentcyHigh.getZ6Toz8());
            yList.add(curentcyHigh.getZ8Toz10());
            yList.add(curentcyHigh.getZ10());

            vo.setY(yList);

            graliIntensity.setChart(vo);
            graliIntensity.setExplanation("主要货币中，过去24小时，价格上涨的货币数量越多，整个行情就越高涨，反之，下跌的货币数量越多，整个行情就越低迷。");

            resultVo.setCode(ReturnCode.SUCCESS);
            resultVo.setTradeId(LogTrace.getTrace().getTraceId());
            resultVo.setData(graliIntensity);
            return resultVo;
        }catch (Exception e){
            e.printStackTrace();
            LogTrace.error("涨跌统计",e);
            resultVo.setCode(ReturnCode.ERROR);
            resultVo.setMessage(e.getMessage());
            resultVo.setTradeId(LogTrace.getTrace().getTraceId());
            return  resultVo;
        }
    }


    /**
     * 获取赚钱效应
     * @param type 3H  || 1d
     * @return
     */
    public ApiResultVo<GraliIntensity> getMarkMoneyEffect(int type) {
        Long start = System.currentTimeMillis();
        ApiResultVo<GraliIntensity> resultVo = new ApiResultVo<>();
        GraliIntensity vo = new GraliIntensity();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        try {
            String redisDate = redisServer.get(RedisKeysUtils.MARK_MONEY_EFFECT_FIVE_DATA);
            LogTrace.info("赚钱效应reis查询数据","耗时",String.valueOf(System.currentTimeMillis()-start));
            if(org.apache.commons.lang3.StringUtils.isNotBlank(redisDate)){
                vo = JSON.parseObject(redisDate,GraliIntensity.class);
            }
            if(vo == null || vo.getChart() == null || vo.getChart().getX() == null || vo.getChart().getX().size() == 0){
                resultVo.setCode(ReturnCode.DATA_NOT_EXIST);
                resultVo.setMessage("数据不存在");
                return resultVo;
            }else{
                resultVo.setCode(ReturnCode.SUCCESS);
            }
            Date date = new Date(Long.parseLong(vo.getTime()));
            vo.setTime( DateUtils.dateFormatString(date ,DateTimeFormatter.ofPattern("HH:mm")));
            switch (type){
                case 1:
                    //获取最近三个小时数据
                    ChartVo chartVo = getChartVoByHours(vo.getChart()  , 3);

                    vo.setChart(chartVo);
                    resultVo.setData(vo);
                    break;
                case 2:
                    //1天
                    resultVo.setData(vo);
                    break;
            }

            Long end = System.currentTimeMillis();
            LogTrace.info("赚钱效应","耗时",String.valueOf(end-start));
            return resultVo;
        } catch (Exception e) {
            e.printStackTrace();
            resultVo.setCode(ReturnCode.ERROR);
            resultVo.setMessage(e.getMessage());
            LogTrace.error("赚钱效应",e);
            return resultVo;
        }
    }

    /**
     *
     * @param chart 图表数据
     * @param hours 最近几小时
     * @return
     */
    private ChartVo getChartVoByHours(ChartVo chart , int hours) {

        ChartVo chartVo = new ChartVo();

        List<String> xTime = chart.getX();
        List<String> yData = (List<String>) chart.getY();
        int i = 0;
        for (i = 0 ; i < xTime.size() ; i++) {
            String timeStr = xTime.get(i);
            if(DateUtils.getDaysBetweenTwoHours(new Date() , new Date(Long.parseLong(timeStr)))<=hours){
                break;
            }
        }
        if(i <  xTime.size() -1){
            chartVo.setX(xTime.subList(i  , xTime.size() -1));
            chartVo.setY(yData.subList(i  , yData.size() -1));
        }
        return chartVo;
    }

    /**
     * 权重表现
     * @return
     */
    public ApiResultVo<ApiMarketWeightsPerformance> getMarketWeightsPerformance(int type) {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        ApiMarketWeightsPerformance vo = new ApiMarketWeightsPerformance();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        try {
            String redisDate = redisServer.get(RedisKeysUtils.MARKET_WEIGHTS_PERFORMANCE);
            LogTrace.info("权重表现reis查询数据","耗时",String.valueOf(System.currentTimeMillis()-start));
            if(StringUtils.isNotBlank(redisDate)){
                vo = JSON.parseObject(redisDate,ApiMarketWeightsPerformance.class);
            }
            if(vo == null || vo.getChart() == null || vo.getChart().getX() == null || vo.getChart().getX().size() == 0){
                resultVo.setCode(ReturnCode.DATA_NOT_EXIST);
                resultVo.setMessage("数据不存在");
                return resultVo;
            }

            Date date = new Date(Long.parseLong(vo.getTime()));
            vo.setTime( DateUtils.dateFormatString(date ,DateTimeFormatter.ofPattern("HH:mm")));
            switch (type){
                case 1:
                    //获取最近三个小时数据
                    ChartVo chartVo = getChartVoByHours(vo.getChart()  , 3);
                    vo.setChart(chartVo);
                    resultVo.setData(vo);
                    break;
                case 2:
                    //1天
                    resultVo.setData(vo);
                    break;
            }

            resultVo.setCode(ReturnCode.SUCCESS);
            Long end = System.currentTimeMillis();
            LogTrace.info("权重表现","耗时",String.valueOf(end-start));
            return resultVo;
        } catch (Exception e) {
            e.printStackTrace();
            resultVo.setCode(ReturnCode.ERROR);
            resultVo.setMessage(e.getMessage());
            LogTrace.error("权重表现",e);
            return resultVo;
        }

    }
    /**
     * 量能变化
     * @return
     */
    public ApiResultVo<ApiMarketInterpretationChange> getMarketInterpretationChange(int type) {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        ApiMarketInterpretationChange vo = new ApiMarketInterpretationChange();
        try {
            String redisDate = redisServer.get(RedisKeysUtils.MARKET_INTERPRETATION_CHANGE);
            LogTrace.info("量能变化reis查询数据","耗时",String.valueOf(System.currentTimeMillis()-start));
            if(org.apache.commons.lang3.StringUtils.isNotBlank(redisDate)){
                vo = JSON.parseObject(redisDate,ApiMarketInterpretationChange.class);
            }
            if(vo == null || vo.getChart() == null || vo.getChart().getX() == null || vo.getChart().getX().size() == 0){
                resultVo.setCode(ReturnCode.DATA_NOT_EXIST);
                resultVo.setMessage("数据不存在");
                return resultVo;
            }
            Date date = new Date(Long.parseLong(vo.getTime()));
            vo.setTime( DateUtils.dateFormatString(date ,DateTimeFormatter.ofPattern("HH:mm")));
            switch (type){
                case 1:
                    //获取最近三个小时数据
                    MoreChartVo chartVo = new MoreChartVo();
                    List<String> xTime = vo.getChart().getX();
                    List<String> yData = (List<String>) vo.getChart().getY();
                    List<String> y2Data = (List<String>) vo.getChart().getY2();
                    int i = 0;
                    for (i = 0 ; i < xTime.size() ; i++) {
                        String timeStr = xTime.get(i);
                        if(DateUtils.getDaysBetweenTwoHours(new Date() , new Date(Long.parseLong(timeStr)))<=3){
                            break;
                        }
                    }
                    if(i <  xTime.size() -1){
                        chartVo.setX(xTime.subList(i  , xTime.size() -1));
                        chartVo.setY(yData.subList(i  , yData.size() -1));
                        chartVo.setY2(y2Data.subList(i  , y2Data.size() -1));
                    }
                    vo.setChart(chartVo);
                    resultVo.setData(vo);
                    break;
                case 2:
                    //1天
                    resultVo.setData(vo);
                    break;
            }

            resultVo.setCode(ReturnCode.SUCCESS);
            Long end = System.currentTimeMillis();
            LogTrace.info("量能变化","耗时",String.valueOf(end-start));
            return resultVo;
        } catch (Exception e) {
            e.printStackTrace();
            resultVo.setCode(ReturnCode.ERROR);
            resultVo.setMessage(e.getMessage());
            LogTrace.error("量能变化",e);
            Long end = System.currentTimeMillis();
            LogTrace.info("量能变化","耗时",String.valueOf(end-start));
            return resultVo;
        }
    }

}
